import ArrayUtil from "../../utils/ArrayUtil";
export default class eventUtil {

    private static eventPool: { [key: string]: Array<MListener> } = {};

    /**
    * 添加一个监听者
    * @param {string} eventName 监听的事件名
    * @param {typeof Class} target 监听者
    * @param {Function} callback 监听事件触发后的回调
    * @param {boolean} once 监听事件触发后的回调
    */
    public static addListener(eventName: string, target: any, callback: Function, once: boolean = false) {
        this._addListener(eventName, target, once, callback);
    }
    /**
    * 添加一个监听者
    * @param {string} eventName 监听的事件名
    * @param {typeof Class} target 监听者
    * @param {Function} callback 监听事件触发后的回调
    * @param {boolean} once 监听事件触发后的回调
    */
    public static on(eventName: string, target: any, callback: Function, once: boolean = false) {
        this.addListener(eventName, target, callback, once);
    }


    /**
     * 当前帧立即发送一个事件
     * @param {String} eventName 事件名
     * @param {any} data 自定义数据
     */
    public static sendEventImmediately(eventName: string, data: any) {
        this.dispatchEvent(eventName, data);
    }
    /**
     * 当前帧立即发送一个事件
     * @param {String} eventName 事件名
     * @param {any} data 自定义数据
     */
    public static dispatchEvent(eventName: string, data: any) {

        this._sendEvent(eventName, data);

    }


    public static off(eventName: string, target: any) {
        this.removeListener(eventName, target);
    }

    public static offAll(target: any) {
        this.removeAllListener(target);
    }
    /**
     * 移除一个监听者
     * @param {string} eventName 事件名
     * @param {any} target 监听者
     */
    public static removeListener(eventName: string, target: any): void {
        var isEventNameAvailable = eventName != null && eventName != '';
        if (!isEventNameAvailable) {
            console.error('eventName:' + eventName + '不合法！');
            return;
        }
        if (this.eventPool.hasOwnProperty(eventName)) {
            let listeners = this.eventPool[eventName];
            for (let i = 0; i < listeners.length; i++) {
                let listener = listeners[i];
                if (listener.target === target) {
                    ArrayUtil.remove(listeners, listener);
                    break;
                }
            }
            this.eventPool[eventName] = listeners;
        }
    }

    /**
     * 移除所有监听者
     */
    public static removeAllListener(target?: any): void {
        if (target == null) {
            this.eventPool = {};
        }
        else {
            for (let eventName in this.eventPool) {
                let listeners = this.eventPool[eventName];
                for (let i = 0; i < listeners.length; i++) {
                    let listener = listeners[i];
                    if (listener.target === target) {
                        ArrayUtil.remove(listeners, listener);
                        break;
                    }
                }
                this.eventPool[eventName] = listeners;
            }
        }
    }

    private static _addListener(eventName: string, target: any, once: boolean, callback: Function): void {
        var isEventNameAvailable = eventName != null && eventName != '';
        if (!isEventNameAvailable) {
            console.error('eventName:' + eventName + '不合法！');
            return;
        }
        let listener = new MListener();
        callback instanceof Function ? listener.callback = callback : console.error('callback不是一个方法');
        target ? listener.target = target : console.error('target为空');
        listener.once = once;
        let hasSameEvent = false;
        if (this.eventPool.hasOwnProperty(eventName)) {
            let eventList = this.eventPool[eventName];
            for (let i = 0; i < eventList.length; i++) {
                let event: MListener = eventList[i];
                if (event.target === listener.target) {
                    hasSameEvent = true;
                    break;
                }
            }
            //没有相同事件
            if (!hasSameEvent) {
                this.eventPool[eventName].push(listener);
            }
        }
        else {
            this.eventPool[eventName] = [listener];
        }
    }


    public static _sendEvent(eventName: string, data: any) {
        var isEventNameAvailable = eventName != null && eventName != '';
        if (!isEventNameAvailable) {
            console.error('eventName:' + eventName + '不合法！');
            return;
        }
        if (this.eventPool.hasOwnProperty(eventName)) {
            let listeners = this.eventPool[eventName];
            for (let i = 0; i < listeners.length; i++) {
                let listener = listeners[i];
                listener.callback.call(listener.target, data);
                if (listener.once) {
                    ArrayUtil.remove(listeners, listener);
                    i--;
                }
            }
            this.eventPool[eventName] = listeners;
        }

    }

}

/**
 * 监听者
 */
export class MListener {
    public callback: Function = () => { };
    public target: any = []
    public once: Boolean = false
    constructor() {
        this.callback = () => { };;
        this.target = null;
        this.once = false;
    }
}


